From aeec832f0e88f059f0c3b0ea19577febb8f6bdcc Mon Sep 17 00:00:00 2001 From: Kristian Rietveld Date: Thu, 14 Oct 2010 17:26:17 +0200 Subject: [PATCH] Do not call validate_visible_area() from the draw method Because validate_visible_area() can modify the window size (and thus the underlying surface), it should not be called from within the draw method. Given that the presize handler is run with a higher priority than redraw, and the presize handler will validate the visible area, there should not be cases wherein the draw method is called and validate_visible_area() has not been run yet. However, one such a case was gdk_window_process_updates(), which would trigger the draw method at some point. We now work around this by factoring this in a new gtk_tree_view_bin_process_updates() function that will run the presize handler first if needed. Note: for other platforms, it might still be the case that the draw method is called and validate_visible_area() has not been run yet. (For example the Mac backend calls gdk_window_process_updates() from the drawRect method, and the redraw-in-idle handling thus works differently). This does not seem to be a problem now, if it will be in the future we need to take care of that then. --- gtk/gtktreeview.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index e5fa337047..ff78b3324c 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -4390,8 +4390,6 @@ gtk_tree_view_bin_draw (GtkWidget *widget, return TRUE; } - validate_visible_area (tree_view); - style = gtk_widget_get_style (widget); bin_window_width = gdk_window_get_width (tree_view->priv->bin_window); @@ -6451,6 +6449,21 @@ install_presize_handler (GtkTreeView *tree_view) } } +static void +gtk_tree_view_bin_process_updates (GtkTreeView *tree_view) +{ + /* Prior to drawing, we make sure the visible area is validated. */ + if (tree_view->priv->presize_handler_timer) + { + g_source_remove (tree_view->priv->presize_handler_timer); + tree_view->priv->presize_handler_timer = 0; + + do_presize_handler (tree_view); + } + + gdk_window_process_updates (tree_view->priv->bin_window, TRUE); +} + static gboolean scroll_sync_handler (GtkTreeView *tree_view) { @@ -8908,7 +8921,8 @@ gtk_tree_view_clamp_node_visible (GtkTreeView *tree_view, { /* We process updates because we want to clear old selected items when we scroll. * if this is removed, we get a "selection streak" at the bottom. */ - gdk_window_process_updates (tree_view->priv->bin_window, TRUE); + gtk_tree_view_bin_process_updates (tree_view); + gtk_tree_view_scroll_to_cell (tree_view, path, NULL, FALSE, 0.0, 0.0); gtk_tree_path_free (path); } @@ -10683,7 +10697,7 @@ gtk_tree_view_adjustment_changed (GtkAdjustment *adjustment, } gdk_window_process_updates (tree_view->priv->header_window, TRUE); - gdk_window_process_updates (tree_view->priv->bin_window, TRUE); + gtk_tree_view_bin_process_updates (tree_view); } } -- 2.30.2